import Taro from '@tarojs/taro';
import { BaseModel, CmdSignModel } from '../models/index';
import { getStoreId, cacheService } from '../services';
import { CmdCode } from '../code';

declare let APP_KEY: string;

function guid(): string {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }

  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4();
}

export abstract class ACmd {


  abstract req(): CmdSignModel;

  abstract resp(model: CmdSignModel): void;

  abstract error(model: CmdSignModel): void;

  abstract getCmdCode(): string;

  public afterRespData: any;
  public afterRespDo: (model: CmdSignModel) => void;
  public afterErrorDo: (model: CmdSignModel) => void;
  public afterNetErrorDo: (model: CmdSignModel) => void;

  public setAfterRespDo(respDo: (model: CmdSignModel) => void): ACmd {
    this.afterRespDo = respDo;
    return this;
  }

  public setAfterErrorDo(errorDo: (model: CmdSignModel) => void): ACmd {
    Taro.hideLoading()
    this.afterErrorDo = errorDo;
    return this;
  }

  public setAfterNetErrorDo(errorDo: (model: CmdSignModel) => void): ACmd {
    Taro.hideLoading()
    this.afterNetErrorDo = errorDo;
    return this;
  }

  getCmdVersion(): string {
    return "1";
  }

  protected buildCmdSign(source?: BaseModel | BaseModel[], reqCode?: string): CmdSignModel {
    let sessionToken: string = cacheService.getSessionToken();
    let cmdSign: CmdSignModel = new CmdSignModel();
    cmdSign.scope = this.getScope();
    cmdSign.cmdCode = this.getCmdCode();
    cmdSign.cmdVersion = this.getCmdVersion();
    cmdSign.reqCode = reqCode;
    cmdSign.returnStruct = this.returnStruct();
    if (this.returnStruct()) {
      cmdSign.returnStruct = JSON.stringify(this.returnStruct());
    }
    if (sessionToken) {
      cmdSign.sessionToken = sessionToken;
    }
    cmdSign.token = guid();
    if (source) {
      cmdSign.source = JSON.stringify(source);
    }

    return cmdSign;
  }

  showLoading(): boolean {
    return true;
  }


  getScope(): string {
    return 'STORE'
  }

  returnStruct(): any {
    return null;
  }

  setParams(params: any) {

  }
}

export abstract class AHttpCmd extends ACmd {
  public error(model: CmdSignModel): void {
  }
}

export abstract class APageHttpCmd extends AHttpCmd {
  pageSize: number = 10;
  pageIndex: number = 1;

  protected buildCmdSign(source?: BaseModel, reqCode?: string): CmdSignModel {
    let cmdSign: CmdSignModel = super.buildCmdSign(source, reqCode);
    cmdSign.pageSize = this.pageSize;
    if (source && source.pageIndex) {
      cmdSign.pageIndex = source.pageIndex;
    } else {
      cmdSign.pageIndex = this.pageIndex;
    }
    return cmdSign;
  }
}
